package com.wetool.wechat.controller;

import com.wetool.common.model.Message;
import com.wetool.common.model.Result;
import com.wetool.common.model.UserType;
import com.wetool.common.wechat.WechatResult;
import com.wetool.common.wechat.WechatSignInRequest;
import com.wetool.common.wechat.WechatSignUpRequest;
import com.wetool.wechat.entity.WechatAccountRelation;
import com.wetool.wechat.jpa.WechatAccountRelationRepo;
import com.wetool.wechat.model.open.WechatAccessTokenResponse;
import com.wetool.wechat.service.WechatOAuthService;
import com.wetool.wechat.service.WechatOfficialService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * 微信OAuth认证接口
 */
@Api(description = "微信OAuth认证接口")
@RestController()
public class WechatOAuthController {

    private final static Logger LOGGER = LoggerFactory.getLogger(WechatOAuthController.class);

    @Autowired
    private WechatOAuthService wechatOAuthService;

    @Autowired
    private WechatAccountRelationRepo wechatAccountRelationRepo;

    @Autowired
    private WechatOfficialService wechatOfficialService;

    /**
     * 微信登录接口（仅作登录认证，不做登录操作）
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "微信登录(仅验证权限)", notes = "需要微信回调后给出的code以及state参数作为认证参数")
    @ApiResponses(value = {
            @ApiResponse(code = 0, message = "操作成功"),
            @ApiResponse(code = 1, message = "操作成功"),
            @ApiResponse(code = 161105, message = "用户未注册微兔帐号", response = WechatResult.class),
            @ApiResponse(code = 161106, message = "用户未关注微兔公众号", response = WechatResult.class)
    })
    @PostMapping(value = "/wechat/sign-in")
    public ResponseEntity<Message<?>> wechatSignIn(@RequestBody WechatSignInRequest request) {
        LOGGER.info("进入接口：微信登录  >  code:{},state:{},role:{}", request.getCode(), request.getState(), request.getUserType());

        //TODO state checked

        Message<?> message;
        WechatAccessTokenResponse wechatAccessToken = this.wechatOAuthService.accessToken(request.getCode());
        //检查accessToken有效性，失败则直接返回
        if (wechatAccessToken == null || StringUtils.isEmpty(wechatAccessToken.getOpenId())) {
            //提示错误
            return ResponseEntity.ok(new Message<>(WechatResult.OAUTH_ERROR));
        }

        //通过开放平台openId 查询扫码用户的微信账户存档
        WechatAccountRelation accountRelation = this.wechatAccountRelationRepo.findByOpenPlatformOpenId(wechatAccessToken.getOpenId());
        //检测当前用户unionid
        if (accountRelation == null || StringUtils.isEmpty(accountRelation.getUnionId())) {
            //如果当前用户没有被记录过，则获取unionId并记录用户的微信账户
            String unionId = wechatAccessToken.getUnionId();
            unionId = StringUtils.isEmpty(unionId) ? this.wechatOAuthService.getUserInfo(wechatAccessToken.getAccessToken(), wechatAccessToken.getOpenId()).getUnionid() : unionId;
            this.wechatAccountRelationRepo.save(new WechatAccountRelation(unionId, wechatAccessToken.getOpenId()));
            //执行注册
            message = new Message<>(WechatResult.OAUTH_USER_UNREGISTERED, null, unionId);
        }
        //否则检查用户当前绑定状态
        else {
            //存在绑定关系
            if (accountRelation.getUserId() != null && accountRelation.getUserId() > 1) {
                //执行认证
                message = this.wechatOAuthService.verifyWechatUser(accountRelation.getUserId(), request.getUserType());
                accountRelation.clearTicket();
                this.wechatAccountRelationRepo.save(accountRelation);
            } else {
                //执行注册
                message = new Message<>(WechatResult.OAUTH_USER_UNREGISTERED, null, accountRelation.getUnionId());
            }
        }

        // 验证微信用户身份
        LOGGER.info("退出接口:微信登录 < 返回参数【{}】", message);
        return ResponseEntity.ok(message);
    }


    /**
     * @return
     */
    @ApiOperation(value = "微信用户注册", notes = "绑定微信id以及微兔id")
    @PostMapping(value = "/wechat/sign-up")
    public ResponseEntity<Message<?>> wechatSignUp(@RequestBody WechatSignUpRequest request) {
        LOGGER.info("进入接口：微信注册  >  参数:{}", request);

        //校验微信帐号
        WechatAccountRelation accountRelation = this.wechatAccountRelationRepo.findOne(request.getUnionId());

        if (accountRelation == null) {
            return ResponseEntity.ok(new Message<>(Result.ERROR, "当前注册申请无效，没有匹配的unionId"));
        }

        if (accountRelation.getUserId() != null && accountRelation.getUserId() > 1) {
            return ResponseEntity.ok(new Message<>(Result.ERROR, "当前微信用户已经绑定微兔帐号，如果无法登录请联系客服"));
        }

        //提交注册
        Message<?> message = this.wechatOAuthService.signUpWechatUser(request);

        if (message.getCode() != Result.SUCCESS.getCode()) {
            return ResponseEntity.ok(message);
        }

        //绑定微信账户与微兔账户信息
        Map<String, Object> data = (Map<String, Object>) message.getData();

        Integer userId = (Integer) data.get("userId");
        accountRelation.bindUserId(userId);
        this.wechatAccountRelationRepo.save(accountRelation);
        //返回用户名以及密码
        message = this.wechatOAuthService.verifyWechatUser(accountRelation.getUserId(), request.getUserType());
        accountRelation.clearTicket();
        this.wechatAccountRelationRepo.save(accountRelation);
        LOGGER.info("结束接口：微信注册  <  参数:{}", message);
        return ResponseEntity.ok(message);
    }


    /**
     * @return
     */
    @ApiOperation(value = "创建微信二维码")
    @GetMapping(value = "/wechat/qrcode")
    public ResponseEntity<?> wechatCreateQrCode(Long merchantId) {
    	LOGGER.info("进入接口：创建微信二维码（商家关注）  >   merchantId:{}", merchantId);
        Message<?> message = this.wechatOfficialService.createQrCode(merchantId);
        LOGGER.info("结束接口：创建微信二维码（商家关注）   message：{}",  message);
        return ResponseEntity.ok(message);
    }

    @ApiOperation(value = "查询二维码状态（用户注册/登录状态）")
    @GetMapping(value = "/wechat/sign-in")
    public ResponseEntity<?> wechatSignIn(String ticket) {
        LOGGER.info("进入接口：查询微信二维码扫码状态  >   ticket:{}", ticket);

        if (StringUtils.isEmpty(ticket)) {
            return ResponseEntity.ok(new Message<>(Result.ERROR, "参数错误"));
        }

        WechatAccountRelation account = this.wechatAccountRelationRepo.findByTicket(ticket);
        Message<?> message;
        if (account == null) {
            message = new Message<>(WechatResult.WECHAT_QRCODE_TICKET_NOT_FOUND);
            return ResponseEntity.ok(message);
        }

        if (account.getUserId() == null || account.getUserId() < 1) {
            //注册
            message = new Message<>(WechatResult.OAUTH_USER_UNREGISTERED, null, account.getUnionId());
        } else {
            //登录
            message = this.wechatOAuthService.verifyWechatUser(account.getUserId(), UserType.service);
            account.clearTicket();
            this.wechatAccountRelationRepo.save(account);

        }
        LOGGER.info("结束接口：查询微信二维码扫码状态  <   参数：{}", message);

        return ResponseEntity.ok(message);
    }
}
